/*=====================================================================================================================
                    Copyright(c) 2009 Geometric PLM Software Corp. All rights reserved.
                             Unpublished - All rights reserved
=======================================================================================================================
File description:
    Filename: tc_item.c
    Module  : (geometric) itk module.

        This file manages the operations of the item.

=======================================================================================================================
Date               Name              Description of Change
14-Jul-2009        Penn,Xie          Initialize creation
$HISTORY$
=====================================================================================================================*/
// {{ FOR IMAN 
#ifdef BUILD_IMAN 
#include <imantype.h>

#define GTCTYPE_find_type       IMANTYPE_find_type
#define GTC_master_form_rtype   IMAN_master_form_rtype

#else // Teamcenter
#include <tccore\tctype.h>

#define GTCTYPE_find_type       TCTYPE_find_type
#define GTC_master_form_rtype   TC_master_form_rtype

#endif
// }}
#include <tccore\grm.h>
#include <tccore\grmtype.h>
#include <tccore\item.h>
#include <ai\sample_err.h>
#include <ps\ps.h>

#include "list_c.h"
#include "tc_item.h"

#define LIST_NODE_TYPE tag_t
#

int GITEM_get_master_revision( tag_t itemTagOrItemRevTag, tag_t *masterTag )
{
    int   ifail         = ITK_ok;

    tag_t typeTag       = NULL_TAG;
    int   count         = 0;
    tag_t *secondaryTag = NULL;

    *masterTag = NULLTAG;

    ifail = GTCTYPE_find_type( GTC_master_form_rtype, NULL, &typeTag );
    if (ifail != ITK_ok)
        return ifail;

    // item revision is ok
    ifail = GRM_list_secondary_objects_only( itemTagOrItemRevTag, typeTag, &count, &secondaryTag );
    if (ifail != ITK_ok)
        return ifail;

    if (count == 1)
        *masterTag = secondaryTag[0];
    else if (count > 1)
        ifail = GRM_duplicate_relations_exist;
    else
        ifail = GRM_relation_does_not_exist;

    return ifail;
}


int GITEM_get_latest_revision( tag_t item, logical hasStatus, logical isBased, tag_t *itemRev )
{
    int revCount = 0, baselineRevCount = 0, i = 0, ifail = ITK_ok;
    tag_t *revList = NULL, *baselineRevs = NULL;
    *itemRev = NULL_TAG;
    CALL( ITEM_list_all_revs(item, &revCount, &revList) );
    DO(ifail = GITEM_list_baselineRevs(item, NULL, &baselineRevCount, &baselineRevs));
    if(ifail == ITK_ok)
    {
        for(i = revCount-1; i >= 0; i--)
        {
            logical revHasStatus = false, revIsBased = false;
            int   statusCount = 0, j = 0;
            tag_t *statusList = NULL;

            char rev_id[ITEM_id_size_c+1] = {0};

            for(j=0; j<baselineRevCount; j++)
            {
                if(baselineRevs[j] == revList[i])
                {
                    revIsBased = true;
                    break;
                }
            }
            DO(ifail = WSOM_ask_release_status_list(revList[i], &statusCount, &statusList));
            MEM_free(statusList);
            statusList = NULL;
            if(statusCount > 0)
            {
                revHasStatus = true;
            }
            if(revIsBased == isBased && revHasStatus == hasStatus)
            {
                *itemRev = revList[i];
                break;
            }
        }
    }
    
    return ifail;
}

int GITEM_getBVRbyViewType( tag_t itemRev, tag_t viewType, tag_t *bvr )
{
    int ifail = ITK_ok;
    int nCount = 0, i = 0;
	tag_t *bvrlist = NULL;

    *bvr = NULL_TAG;
	CALL(ITEM_rev_list_all_bom_view_revs(itemRev, &nCount, &bvrlist));
	for (i = 0; i < nCount; i++)
	{
        tag_t bv = NULL_TAG, typeTag = NULL_TAG;
        char *viewName = NULL;
        DO(ifail = PS_ask_bom_view_of_bvr(bvrlist[i], &bv));
        if(ifail == ITK_ok)
        {
            DO(ifail = PS_ask_bom_view_type(bv, &typeTag));
            if(ifail == ITK_ok)
            {
                if(typeTag == viewType)
                {
                    *bvr = bvrlist[i];
                    break;
                }
            }
        }
        if(ifail != ITK_ok)
        {
            break;
        }
    }
    MEM_free(bvrlist);
    return ifail;    
}

int GITEM_list_baselineRevs(tag_t item, const char *baselineStatusName, int *n_revs, tag_t **baseline_revs)
{
    int revCount = 0, i = 0, ifail = ITK_ok;
    tag_t *revList = NULL;
    List_Node_t *tagList= NULL;

    *n_revs = 0;
    *baseline_revs = NULL;

    CALL(ITEM_list_all_revs(item, &revCount, &revList));

    for(i=0; i<revCount; i++)
    {
        int curRevsCount = 0, j = 0;
        tag_t *curBaselineRevs = NULL;
        
        DO(ifail = ITEM_rev_list_baselineRevs(revList[i], baselineStatusName, &curRevsCount, &curBaselineRevs));
        if(ifail != ITK_ok)
        {
            break;
        }
        for(j=0; j<curRevsCount; j++)
        {
            tagList = LIST_insert(tagList, &curBaselineRevs[j]);
        }
    }
    MEM_free(revList);
    if(ifail == ITK_ok)
    {
        List_Node_t *curNode = NULL;
        *n_revs = LIST_size(tagList);
        *baseline_revs = MEM_alloc((*n_revs)*(sizeof(tag_t)));
        for(curNode=LIST_begin(tagList), i = 0; curNode!=NULL; curNode = LIST_getNextNode(curNode), i++)
        {
            (*baseline_revs)[i] = *(tag_t*)(curNode->data);
        }
    }
    else
    {
        *n_revs = 0;
        MEM_free(baseline_revs);
        baseline_revs = NULL;
    }
    LIST_clear(&tagList, MEM_free);
    return ifail;
}
